package example.demo.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import demo.rao.mideng.annotation.RaoMiDeng;
import example.demo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.*;

@Service
public class MiDengService {
    @Autowired
    JdbcTemplate jdbcTemplate;

    Class<User> userClass = User.class;

    @Transactional
    @RaoMiDeng
    public int update(User user) {
        Field[] declaredFields = userClass.getDeclaredFields();
        final Map<String, Object> kv = new HashMap<>(declaredFields.length);
        Arrays.stream(declaredFields)
                .map(field -> {//设置强制访问
                    field.setAccessible(true);
                    return field;
                })
                .filter(field -> {//过滤掉属性为null的
                    Object o = null;
                    try {
                        o = field.get(user);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    return o != null;
                }).forEach(field -> {
            try {
                kv.put(field.getName(), field.get(user));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        });
        Set<String> strings = kv.keySet();
        if (!kv.containsKey("id") && kv.size() >= 2) {
            throw new RuntimeException("please input id");
        }
        Iterator<String> iterator = strings.iterator();
        //没考虑类的字段名与表名不相同的,此处拼接sql。。。
        StringBuilder builder = new StringBuilder("update tb_user set ");
        Object[] values = new Object[strings.size()];
        int idx = 0;
        while (iterator.hasNext()) {
            String columnname = iterator.next();
            if (columnname.equals("id")) {
                continue;
            }
            values[idx++] = kv.get(columnname);
            builder.append(String.format(" %s=? , ", columnname));
        }
        builder.replace(builder.lastIndexOf(","), builder.lastIndexOf(",") + 1, "");
        values[strings.size() - 1] = kv.get("id");
        builder.append("where id = ?");
        String sql = builder.toString();
        return jdbcTemplate.update(sql, values);
    }

    @RaoMiDeng
    @Transactional
    public int insert(User user) {
        //insert into tb_user ()  values ()
        JSONObject jsonObject = (JSONObject) JSON.toJSON(user);
        int size = jsonObject.size();
        StringBuilder builder = new StringBuilder("insert into tb_user ( ");
        Iterator<Map.Entry<String, Object>> iterator = jsonObject.entrySet().iterator();
        int idx = 0;
        Object[] values = new Object[size];

        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            if (next.getValue() == null) {
                iterator.remove();
                continue;
            }
            builder.append(next.getKey() + ", ");
            values[idx++] = next.getValue();
        }
        builder.replace(builder.lastIndexOf(","), builder.lastIndexOf(",") + 1, "");
        builder.append(") values (");
        for (int i = 0; i < idx; i++) {
            if (i != idx - 1) {
                builder.append("? ,");
            } else {
                builder.append("? )");
            }
        }
        Object[] vals = new Object[idx];
        //trim
        System.arraycopy(values, 0, vals, 0, idx);
        String sql = builder.toString();
        return jdbcTemplate.update(sql, vals);
    }

    @Transactional
    @RaoMiDeng
    public int updateIncrAge(Integer userId) {
        return jdbcTemplate.update("update tb_user set age=age+1   where id=?", userId);
    }
//    public static void main(String[] args) {
//        User user = new User(1, "Wahaha", null, "yyy");
//        MiDengService miDengService = new MiDengService();
//        miDengService.insert(user);
//    }

    public User query(User paramObj) {
        StringBuilder builder = new StringBuilder("select * from tb_user where ");
        JSONObject jsonObject = (JSONObject) JSON.toJSON(paramObj);
        Set<Map.Entry<String, Object>> entries = jsonObject.entrySet();
        Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
        Object[] values = new Object[entries.size()];
        int i = 0;
        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            if (next.getValue() == null) {
                continue;
            }
            builder.append(next.getKey() + "=? and ");
            values[i++] = next.getValue();
        }
        builder.replace(builder.lastIndexOf("and"), builder.lastIndexOf("and") + "and".length(), "");
        String sql = builder.toString();
        Object[] vals = new Object[i];
        //进行trim，不这样的话。数组下标越界异常
        System.arraycopy(values, 0, vals, 0, i);
        List<User> query = jdbcTemplate.query(sql, vals, new BeanPropertyRowMapper<>(User.class));
        return query.get(0);
    }

//    public static void main(String[] args) {
//        User user = new User(1, "Wahaha", null, "yyy");
//        MiDengService miDengService = new MiDengService();
//        miDengService.query(user);
//    }
}
